package cn.itsource.ymcc.service.impl;

import cn.itsource.ymcc.constant.RConst;
import cn.itsource.ymcc.domain.*;
import cn.itsource.ymcc.feign.ESCourseFeign;
import cn.itsource.ymcc.feign.MediaFeign;
import cn.itsource.ymcc.mapper.*;
import cn.itsource.ymcc.producer.ICourseProducer;
import cn.itsource.ymcc.result.JsonResult;
import cn.itsource.ymcc.service.ICourseService;
import cn.itsource.ymcc.utils.AssertUtil;
import cn.itsource.ymcc.vo.CourseVo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.sql.SQLOutput;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zongcj
 * @since 2023-09-14
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {
    @Autowired
    private CourseDetailMapper courseDetailMapper;
    @Autowired
    private CourseMarketMapper courseMarketMapper;
    @Autowired
    private CourseResourceMapper courseResourceMapper;
    @Autowired
    private TeacherMapper teacherMapper;
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private CourseSummaryMapper courseSummaryMapper;
    @Autowired
    private CourseTypeMapper courseTypeMapper;
    @Autowired
    private ESCourseFeign esCourseFeign;
    @Autowired
    private CourseCollectMapper courseCollectMapper;
    @Autowired
    private ICourseProducer courseProducer;
    @Autowired
    private CourseChapterMapper courseChapterMapper;
    @Autowired
    private MediaFeign mediaFeign;


    //外观模式
    @Transactional
    @Override
    public void addCourse(CourseVo course, JSONObject user) {
        //查询老师
        List<Long> teacharIds = course.getTeacharIds();
        //课程主表的处理
        Long courseId = courseHandle(course,teacharIds,user);
        //课程与老师的中间表
        courseAndTeacharHandle(courseId,teacharIds);
        //课程详情
        courseDetailHandle(course.getCourseDetail(),courseId);
        //课程交易信息
        courseMarketHandle(course.getCourseMarket(),courseId);
        //课程资源
        courseResourceHandle(course.getCourseResource(),courseId);
        //课程的销量
        courseSummaryHandle(courseId);
    }

    @Override
    public JsonResult getCourseAllInfo(Long id) {
        Map<String,Object> map = new HashMap<>();
        //写逻辑
        Course byId = super.getById(id);
        map.put("course",byId);

        CourseDetail courseDetail = courseDetailMapper.selectById(id);
        map.put("courseDetail",courseDetail);

        CourseMarket courseMarket = courseMarketMapper.selectById(id);
        map.put("courseMarket",courseMarket);

        CourseResource courseResource = courseResourceMapper
                .selectOne(new LambdaQueryWrapper<CourseResource>()
                .eq(CourseResource::getCourseId, id));
        map.put("courseResource",courseResource);

        List<Long> longs = courseMapper.selectTeacharIdByCourseId(id);
        map.put("teacharIds",longs);

        Long courseTypeId = byId.getCourseTypeId();
        CourseType courseType = courseTypeMapper.selectById(courseTypeId);
        map.put("courseType",courseType);

        return JsonResult.success().setData(map);
    }

    @Override
    public JsonResult onLineCourse(List<Long> ids) {
        //这里里面可能有上线的
        List<Course> courses = courseMapper
                                .selectList(new LambdaQueryWrapper<Course>()
                                .eq(Course::getStatus, RConst.Num.BASE_LONG_0)
                                .in(Course::getId, ids));
//        List<Course> courses = courseMapper.selectBatchIds(ids);
        //找只要未上线的
        List<Course> collect = courses.stream()
//                .filter(course -> course.getStatus() == 0)//过滤出来全是未上线的
                .map(course -> {
                    course.setStatus(RConst.Num.INT_1);
                    course.setOnlineTime(new Date());
                    return course;
                }).collect(Collectors.toList());

        //根据id去做批量修改
        super.updateBatchById(collect);
        //构建CourseDoc
        List<CourseDoc> courseDocs = BuilderCourseDocs(collect);
        JsonResult save = esCourseFeign.save(courseDocs);
        //发送消息
        courseProducer.sendAll(courses.stream().map(Course::getId).collect(Collectors.toList()));
        return save;
    }

    @Override
    public JsonResult getCourseDetailData(Long courseId) {
        //我们应该去查询es？
        JsonResult jsonResult = esCourseFeign.selectByCourseId(courseId);
        String string = jsonResult.getData().toString();
        CourseDoc data = JSONObject.parseObject(string, CourseDoc.class);
        AssertUtil.isNotNull(data,"未查询到课程数据");

        Map<String,Object> map = new HashMap<>();
        Course course = new Course();
        BeanUtils.copyProperties(data,course);
        map.put("course",course);
        CourseMarket courseMarket = new CourseMarket();
        BeanUtils.copyProperties(data,courseMarket);
        courseMarket.setPrice(new BigDecimal(data.getPrice()));
        courseMarket.setPriceOld(new BigDecimal(data.getPriceOld()));
        map.put("courseMarket",courseMarket);

        List<CourseChapter> courseChapters = courseChapterMapper.selectList(new LambdaQueryWrapper<CourseChapter>()
                .eq(CourseChapter::getCourseId, courseId));
        JsonResult jsonResult1 = mediaFeign.selectByCourseId(courseId);
        if(jsonResult1.getSuccess()){
            String string1 = jsonResult1.getData().toString();
            List<MediaFile> mediaFiles = JSON.parseArray(string1, MediaFile.class);
            for (CourseChapter courseChapter : courseChapters) {
                for (MediaFile mediaFile : mediaFiles) {
                    if(courseChapter.getId().equals(mediaFile.getChapterId())){
                        List<MediaFile> mediaFiles1 = courseChapter.getMediaFiles();
                        mediaFiles1.add(mediaFile);
                    }
                }
            }
        }
        map.put("courseChapters",courseChapters);
        List<Teacher> teacherList = teacherMapper.selectByCourseId(courseId);
        map.put("teachers",teacherList);

        CourseDetail courseDetail = new CourseDetail();
        BeanUtils.copyProperties(data,courseDetail);
        map.put("courseDetail",courseDetail);

        CourseSummary courseSummary = new CourseSummary();
        BeanUtils.copyProperties(data,courseSummary);
        map.put("courseSummary",courseSummary);


        return JsonResult.success().setData(map);
    }

    private List<CourseDoc> BuilderCourseDocs(List<Course> collect) {
        List<CourseDoc> courseDocs = new ArrayList<>();
        for (Course course : collect) {
            CourseDoc courseDoc = new CourseDoc();
            BeanUtils.copyProperties(course,courseDoc);

            CourseType courseType = courseTypeMapper.selectById(course.getCourseTypeId());
            courseDoc.setCourseTypeName(courseType.getName());
            courseDoc.setStartTime(course.getStartTime().getTime());
            courseDoc.setEndTime(course.getEndTime().getTime());
            courseDoc.setOnlineTime(course.getOnlineTime().getTime());

            CourseDetail courseDetail = courseDetailMapper.selectById(course.getId());
            BeanUtils.copyProperties(courseDetail,courseDoc);

            CourseMarket courseMarket = courseMarketMapper.selectById(course.getId());
            BeanUtils.copyProperties(courseMarket,courseDoc);
            courseDoc.setPrice(courseMarket.getPrice().doubleValue());
            courseDoc.setPriceOld(courseMarket.getPriceOld().doubleValue());

            CourseSummary courseSummary = courseSummaryMapper.selectById(course.getId());
            BeanUtils.copyProperties(courseSummary,courseDoc);

            Integer integer = courseCollectMapper.selectCount(new LambdaQueryWrapper<CourseCollect>()
                    .eq(CourseCollect::getCourseId, course.getId()));
            courseDoc.setCollectCount(integer);

            courseDocs.add(courseDoc);
        }
        return courseDocs;
    }

    private void courseSummaryHandle(Long courseId) {
        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setId(courseId);
        courseSummary.setCommentCount(RConst.Num.INT_0);
        courseSummary.setSaleCount(RConst.Num.INT_0);
        courseSummary.setViewCount(RConst.Num.INT_0);
        courseSummaryMapper.insert(courseSummary);
    }

    private void courseResourceHandle(CourseResource courseResource, Long courseId) {
        courseResource.setCourseId(courseId);
        courseResourceMapper.insert(courseResource);
    }

    private void courseMarketHandle(CourseMarket courseMarket, Long courseId) {
        courseMarket.setId(courseId);
        courseMarketMapper.insert(courseMarket);
    }

    private void courseDetailHandle(CourseDetail courseDetail, Long courseId) {
        courseDetail.setId(courseId);
        courseDetailMapper.insert(courseDetail);
    }

    private void courseAndTeacharHandle(Long courseId, List<Long> teacharIds) {
        courseMapper.insertCourseTeachar(courseId,teacharIds);
    }


    private Long courseHandle(CourseVo courseVo,List<Long> teacharIds,JSONObject user){
        List<Teacher> teachers = teacherMapper.selectBatchIds(teacharIds);
        //拼接老师名字
        String teacherNames = teachers.stream().map(Teacher::getName).collect(Collectors.joining(RConst.Str.COMMA));
        Course course = courseVo.getCourse();
        course.setTeacherNames(teacherNames);
        course.setStatus(RConst.Num.INT_0);//课程状态，下线：0 ， 上线：1
        course.setLoginId(Long.valueOf(user.get("id").toString()));
        course.setLoginUserName(user.get("username").toString());
        super.save(course);
        return course.getId();
    }
}
